package org.examples.java.lang;

import static org.junit.Assert.assertEquals;

import java.util.concurrent.Semaphore;

import org.junit.Test;

public class InheritableThreadLocalTest {

    private InheritableThreadLocal<String> localString = new InheritableThreadLocal<String>();

    @Test
    public void testGetSetInSingleThread() {
        localString.set("AAA");
        assertEquals("AAA", localString.get());
        localString.remove();
        assertEquals(null, localString.get());
    }


    @Test
    public void testTwoThreads() throws InterruptedException {
        localString.set("1");

        final Semaphore semaphore = new Semaphore(0);
        final Semaphore semaphore2 = new Semaphore(0);
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                // the value is inherited from parent thread
                assertEquals("1", localString.get());
                semaphore.release();
                try {
                    semaphore2.acquire();
                }
                catch(InterruptedException e) {
                }
                // though ThreadLocal value was changed to "3" in main thread, the value in child stays the same
                assertEquals("1", localString.get());
                localString.set("2");
            }
        });
        thread.start();
        semaphore.acquire();

        localString.set("3");
        semaphore2.release();

        thread.join(1000);

        assertEquals("3", localString.get());
    }
}
